package com.yuda.afterexamscore.controller;

import com.yuda.afterexamscore.domain.SpartaSubject;
import com.yuda.afterexamscore.domain.SpotCheckAnswer;
import com.yuda.afterexamscore.service.SpotCheckAnswerService;
import com.yuda.afterexamscore.vo.DpQuesScoreVo;
import com.yuda.common.core.constant.HttpStatus;
import com.yuda.common.core.web.controller.BaseController;
import com.yuda.common.core.web.domain.AjaxResult;
import com.yuda.common.core.web.page.PageDomain;
import com.yuda.common.core.web.page.TableDataInfo;
import com.yuda.common.core.web.page.TableSupport;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;

@Api("抽查答案")
@RestController
@RequestMapping("/spotCheckAnswer")
@RefreshScope
public class SpotCheckAnswerController extends BaseController {
    @Autowired
    private  SpotCheckAnswerService spotCheckAnswerService;

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Value("${examUUID}")
    private String examUUID;

    private static Logger log = LoggerFactory.getLogger(SpotCheckAnswerController.class);

    private static String process = "0";

    public static Queue<DpQuesScoreVo> dpSubjectScoreQueue = new ConcurrentLinkedQueue<DpQuesScoreVo>();

    public static Queue<Object[]> objectQueue = new ConcurrentLinkedQueue<>();

    /**
     * 总分查看算分来源
     *
     * @author fmx
     * @date 2021-05-30
     */
    @ApiOperation("总分抽验答案列表,传准考证")
    @GetMapping("/queryAnswerSource")
    public AjaxResult queryAnswerSource(String zkz_num) {
        List<SpotCheckAnswer> answerSources = jdbcTemplate.query("SELECT a.subject_id,b.name subjectName,a.answer_source,a.mq_status \n" +
                "from sparta_exam_subject_student a\n" +
                "LEFT JOIN sparta_subject b on a.subject_id = b.id \n" +
                "where zkz_num = ? and quekao != 1 and stu_start_time != 0", new Object[]{zkz_num}, new BeanPropertyRowMapper<>(SpotCheckAnswer.class));
        return AjaxResult.success(answerSources);
    }

    /**
     * 总分抽验答案列表
     *
     * @author fmx
     * @date 2021-05-30
     */
    @ApiOperation("总分抽验答案列表")
    @GetMapping("/querySpotCheckAnswerTotal")
    public TableDataInfo querySpotCheckAnswerTotal(SpotCheckAnswer spotCheckAnswer) {
        List<SpotCheckAnswer> spotCheckAnswers = spotCheckAnswerService.querySpotCheckAnswerTotal(spotCheckAnswer);
        int size = spotCheckAnswers.size();
        PageDomain pageDomain = TableSupport.buildPageRequest();
        Integer pageNum = pageDomain.getPageNum();
        Integer pageSize = pageDomain.getPageSize();
        int fromIndex = (pageNum-1)*pageSize;
        if (fromIndex > size){
            int yuShu = size % pageSize;
            spotCheckAnswers = spotCheckAnswers.subList(size-yuShu,size);
        }else {
            int toIndex = pageNum*pageSize;
            if (toIndex > size){
                toIndex = size;
            }
            spotCheckAnswers = spotCheckAnswers.subList(fromIndex,toIndex);
        }
        TableDataInfo rspData = new TableDataInfo();
        rspData.setCode(HttpStatus.SUCCESS);
        rspData.setRows(spotCheckAnswers);
        rspData.setMsg("查询成功");
        rspData.setTotal(size);
        return rspData;
    }

    /**
     * 单科查询科目种类
     * 2021年6月16日
     * @author fmx
     * @date 2021-05-30
     */
    @ApiOperation("单科抽查分数需要的subejct_id")
    @GetMapping("/querySpotCheckSubject")
    public AjaxResult querySpotCheckSubject() {
        List<SpartaSubject> answerSources = jdbcTemplate.query("SELECT a.subject_id id,a.relation_subject_id, CONCAT(b.desc,':',b.name) name from sparta_exam_subject_student a LEFT JOIN sparta_subject b on a.subject_id = b.id GROUP BY a.subject_id", new BeanPropertyRowMapper<>(SpartaSubject.class));
        return AjaxResult.success(answerSources);
    }

    /**
     * 单科抽验答案列表
     *
     * @author fmx
     * @date 2021-05-30
     */
    @ApiOperation("单科抽验答案列表，2021年6月16日修改,必须传入SubjectId")
    @GetMapping("/querySpotCheckAnswerSubject")
    public TableDataInfo querySpotCheckAnswerSubject(SpotCheckAnswer spotCheckAnswer) {
        List<SpotCheckAnswer> spotCheckAnswers = spotCheckAnswerService.querySpotCheckAnswer(spotCheckAnswer);
//        if (spotCheckAnswer.getUnfortunatelyNum()!=null){
//            List<SpotCheckAnswer> spotCheckAnswerUnfortunates = spotCheckAnswerService.querySpotCheckAnswerUnfortunate(spotCheckAnswer);
//            spotCheckAnswers.addAll(spotCheckAnswerUnfortunates);
//        }
//        spotCheckAnswers = spotCheckAnswers.stream().collect(
//                Collectors.collectingAndThen(Collectors.toCollection(
//                        () -> new TreeSet<>(Comparator.comparing(o -> o.getStudentId()))), ArrayList::new)
//        );
//        spotCheckAnswers.sort(Comparator.comparing(SpotCheckAnswer::getRank));
        int size = spotCheckAnswers.size();
        PageDomain pageDomain = TableSupport.buildPageRequest();
        Integer pageNum = pageDomain.getPageNum();
        Integer pageSize = pageDomain.getPageSize();
        int fromIndex = (pageNum-1)*pageSize;
        if (fromIndex > size){
            int yuShu = size % pageSize;
            spotCheckAnswers = spotCheckAnswers.subList(size-yuShu,size);
        }else {
            int toIndex = pageNum*pageSize;
            if (toIndex > size){
                toIndex = size;
            }
            spotCheckAnswers = spotCheckAnswers.subList(fromIndex,toIndex);
        }
        TableDataInfo rspData = new TableDataInfo();
        rspData.setCode(HttpStatus.SUCCESS);
        rspData.setRows(spotCheckAnswers);
        rspData.setMsg("查询成功");
        rspData.setTotal(size);
        return rspData;
    }

    /**
     * 修改抽验状态
     *
     * @author fmx
     * @date 2021-05-30
     *
     */
    @ApiOperation("修改抽验状态,总分需要zkzNum,spotCheckStatus,e_status,单科需要zkzNum,spotCheckStatus,subject_id")
    @PutMapping("/updateSpotCheckStatus")
    public AjaxResult updateSpotCheckStatus(@RequestBody SpotCheckAnswer spotCheckAnswer) {
        if (spotCheckAnswer != null && spotCheckAnswer.getSubjectId()!=null){
            //修改单科
            jdbcTemplate.update("UPDATE sparta_exam_subject_student set spot_check_status = ? where zkz_num = ? and subject_id = ?",new Object[]{spotCheckAnswer.getSpotCheckStatus(),spotCheckAnswer.getZkzNum(),spotCheckAnswer.getSubjectId()});
        }else {
            //修改总分
            jdbcTemplate.update("UPDATE sparta_exam_student set spot_check_status = ? where zkz_num = ? and e_status = ?",new Object[]{spotCheckAnswer.getSpotCheckStatus(),spotCheckAnswer.getZkzNum(),spotCheckAnswer.getE_status()});
        }
        return AjaxResult.success();
    }

    /**
     * mq状态更新，每人每科更新，在算分结束后执行可能有三种状态，mq里没有学生信息的，mq数量不对显示异常，mq数据正常显示正常
     * mq需要更新两张表，一个sparta_exam_student，一个sparta_exam_subject_student
     * @author fmx
     * @date 2021-05-30
     */
    @ApiOperation("mq状态更新,需要找个时机执行")
    @GetMapping("/updateMqStatus")
    public void updateMqType() throws InterruptedException {
        spotCheckAnswerService.updateMqType();
//        //清空队列
//        dpSubjectScoreQueue.clear();
//        objectQueue.clear();
//        //todo 只适用于610 在之后自己的考试中可能会替换
//        List<DpQuesScoreVo> vos = jdbcTemplate.query("SELECT b.student_id,b.subject_id subject_relation_id,IF(b.c=c.c,TRUE,FALSE) mqStatus from\n" +
//                "(\n" +
//                "SELECT student_id,subject_id,count(1) c from \n" +
//                "(\n" +
//                "SELECT student_id,subject_id,ques_id from mq_answer GROUP BY student_id,subject_id,ques_id\n" +
//                ") a GROUP BY student_id,subject_id\n" +
//                ") b,\n" +
//                "(SELECT subject_id,count(1) c from dp_ques_index_mapping GROUP BY subject_id) c\n" +
//                "where b.subject_id=c.subject_id", new BeanPropertyRowMapper<>(DpQuesScoreVo.class));
//        dpSubjectScoreQueue.addAll(vos);
//        //瓜分线程,每个线程处理100条数据
//        ExecutorService executor = Executors.newFixedThreadPool(1000);
//        int threadNum = (int) Math.ceil(vos.size()/100) + 1;
//        if (threadNum>=1){
//            CountDownLatch latch = new CountDownLatch(threadNum);
//            if(threadNum > 0) {
//                for (int i = 0; i < threadNum; i++) { // 开threadNum个线程
//                    Runnable task = new SpotCheckAnswerController.MultithreadingOfUpdateMqStatus(latch);
//                    // 执行
//                    executor.execute(task);
//                }
//            }
//            latch.await(); //
//        }
//        //最后把mq_status状态为null的改为0
//        log.info("把mq_status状态为null的改为0");
//        jdbcTemplate.batchUpdate("update sparta_exam_subject_student set mq_status = 0 where mq_status is null");
//        //在一个sparta_exam_student里更新mq_status状态
//        log.info("查询mq状态");
//        List<SpotCheckAnswer> spotCheckAnswers = jdbcTemplate.query("SELECT student_id,GROUP_CONCAT(mq_status) mq_status from sparta_exam_subject_student where quekao != 1 and stu_start_time != 0 GROUP BY student_id", new BeanPropertyRowMapper<>(SpotCheckAnswer.class));
//        List<Object[]> objects = new ArrayList<>();
//        for (SpotCheckAnswer spotCheckAnswer : spotCheckAnswers) {
//            if (spotCheckAnswer.getMqStatus().contains("0")){
//                objects.add(new Object[]{0,spotCheckAnswer.getStudentId()});
//            }else {
//                objects.add(new Object[]{1,spotCheckAnswer.getStudentId()});
//            }
//        }
//        objectQueue.addAll(objects);
//        int threadNum2 = (int) Math.ceil(objects.size()/100) + 1;
//        if (threadNum2>1){
//            CountDownLatch latch2 = new CountDownLatch(threadNum2);
//            if(threadNum2 > 0) {
//                for (int i = 0; i < threadNum2; i++) { // 开threadNum个线程
//                    Runnable task = new SpotCheckAnswerController.MultithreadingOfUpdateMqStatusTotal(latch2);
//                    // 执行
//                    executor.execute(task);
//                }
//            }
//            latch2.await(); //
//        }
//        executor.shutdown();//关闭线程池
//        log.info("MQ状态跟新完毕");
    }

//    //---------------------------------------------------分割线--------------------------------------------------------------------------------------------------
//
//
//    /**
//     * 多线程之MQ状态跟新完毕类
//     *
//     */
//    private class MultithreadingOfUpdateMqStatus implements Runnable {
//        private CountDownLatch threadsSignal;
//        public MultithreadingOfUpdateMqStatus(CountDownLatch threadsSignal) {
//            this.threadsSignal = threadsSignal;
//        }
//
//        @Override
//        public void run() {
//            List<Object[]> objects = new CopyOnWriteArrayList<>();
//            for (int i = 0; i < 100; i++) {
//                if (dpSubjectScoreQueue.isEmpty()){
//                    break;
//                }
//                DpQuesScoreVo vo = dpSubjectScoreQueue.poll();//消费-省
//                objects.add(new Object[]{vo.getMqStatus(),vo.getStudentId(),vo.getSubjectRelationId()});
//            }
//            jdbcTemplate.batchUpdate("update sparta_exam_subject_student set mq_status = ? where student_id = ? and subject_id = ?",objects);
//            // 线程结束时计数器减1
//            threadsSignal.countDown();//必须等核心处理逻辑处理完成后才可以减1
//            log.info(Thread.currentThread().getName() + "结束. 还有"+ threadsSignal.getCount() + " 个线程 ");
//        }
//    }
//
//    /**
//     * 多线程之MQ状态跟新完毕类
//     *
//     */
//    private class MultithreadingOfUpdateMqStatusTotal implements Runnable {
//        private CountDownLatch threadsSignal;
//        public MultithreadingOfUpdateMqStatusTotal(CountDownLatch threadsSignal) {
//            this.threadsSignal = threadsSignal;
//        }
//
//        @Override
//        public void run() {
//            List<Object[]> objects = new CopyOnWriteArrayList<>();
//            for (int i = 0; i < 100; i++) {
//                if (objectQueue.isEmpty()){
//                    break;
//                }
//                Object[] poll = objectQueue.poll();//消费-省
//                objects.add(poll);
//            }
//            jdbcTemplate.batchUpdate("UPDATE sparta_exam_student set mq_status = ? where student_id = ?",objects);
//            // 线程结束时计数器减1
//            threadsSignal.countDown();//必须等核心处理逻辑处理完成后才可以减1
//            log.info(Thread.currentThread().getName() + "结束. 还有"+ threadsSignal.getCount() + " 个线程 ");
//        }
//    }
}
